/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */
#pragma once

#include <Config.h>
#include <xml/Stream.h>
#include <Converter.h>

namespace liba
{
namespace animate
{

template<typename K>
class Key : public xml::ObjectANSI
{
public:
	time_float time;

	Key()
	:	time( 0 ),
		value( K() ),
		linear( K() ),
		quadratic( K() ),
		cubic( K() )
	{}

	typedef K key_type;
	K value;
	K linear;
	K quadratic;
	K cubic;

	virtual bool on_attribute( xml::Provider * prov, const std::string & name, const std::string & value )
	{
		if( name == "Value" )
		{
			return converter::convert( value, &this->value );
		}
		if( name == "Linear" )
		{
			return converter::convert( value, &linear );
		}
		if( name == "Quadratic" )
		{
			return converter::convert( value, &quadratic );
		}
		if( name == "Cubic" )
		{
			return converter::convert( value, &cubic );
		}
		if( name == "Time" )
		{
			return converter::convert( value, &time );
		}
		return false;
	}
};

template<>
class Key<std::wstring> : public xml::ObjectUnicode
{
	typedef std::wstring K;
public:
	time_float time;

	Key()
	:	time( 0 ),
		value( K() ),
		linear( K() ),
		quadratic( K() ),
		cubic( K() )
	{}

	typedef K key_type;
	K value;
	K linear;
	K quadratic;
	K cubic;

	virtual bool on_attribute( xml::Provider * prov, const std::wstring & name, const std::wstring & value )
	{
		if( name == L"Value" )
		{
			return converter::convert( value, &this->value );
		}
		if( name == L"Linear" )
		{
			return converter::convert( value, &linear );
		}
		if( name == L"Quadratic" )
		{
			return converter::convert( value, &quadratic );
		}
		if( name == L"Cubic" )
		{
			return converter::convert( value, &cubic );
		}
		if( name == L"Time" )
		{
			return converter::convert( value, &time );
		}
		return false;
	}
};

template<typename K>
class KeyTCB : public xml::ObjectANSI
{
public:
	time_float time;

	KeyTCB()
	:	time( 0 ),
		value( K() ),
		tension( 0 ),
		continuity( 0 ),
		bias( 0 )
	{}

	typedef K key_type;
	K value;
	double tension;
	double continuity;
	double bias;

	virtual bool on_attribute( xml::Provider * prov, const std::string & name, const std::string & value )
	{
		if( name == "Value" )
		{
			return converter::convert( value, &this->value );
		}
		if( name == "Tension" )
		{
			return converter::convert( value, &tension);
		}
		if( name == "Continuity" )
		{
			return converter::convert( value, &continuity );
		}
		if( name == "Bias" )
		{
			return converter::convert( value, &bias );
		}
		if( name == "Time" )
		{
			return converter::convert( value, &time );
		}
		return false;
	}
};

} // namespace animate
} // namespace liba
using namespace liba;

